<%@ page pageEncoding="UTF-8"%>
<%@ include file="import.jsp"%>
<%!
	// 检查时间
	public int checkTime(String str) {
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd EEEE");
			Date dateNow = sdf.parse(str);
			sdf = new SimpleDateFormat("yyyy-MM-dd");
			String date = sdf.format(dateNow);
			boolean flag = date.equals(DateUtil.formatDateByFormat(new Date(), "yyyy-MM-dd"));
			if(!flag) {
				return 3;
			}
			date += " " + DateUtil.formatDateByFormat(new Date(), "HH:mm");
			sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
			String lowStr = DateUtil.formatDate(new Date()) + " " + "09:00";
			String highStr = DateUtil.formatDate(new Date()) + " " + "12:00";
			if (sdf.parse(highStr).getTime() < sdf.parse(date).getTime()) {
				return 2;
			}
			if (sdf.parse(lowStr).getTime() < sdf.parse(date).getTime()) {
				return 1;
			}
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return 0;
	}

	public String[] weeks_check = {"星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"};
	public int getIndex(String week){
		String[] weeks = {"星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"};
		int index = 0;
		for (int i = 0; i < weeks.length; i++) {
			if(weeks[i].equals(week)) {
				index = i;
				break;
			}
		}
		return index;
	}

	//传入星期与要获取的几周
	public List<Map> getPeriodOfTime(String week, int next){
		List<Map> list = new ArrayList<Map>();
		try{
			Calendar cal = Calendar.getInstance();
			SimpleDateFormat sdf = new SimpleDateFormat("EEEE");
			String startTime = sdf.format(cal.getTime());
			int diff = getIndex(week) - getIndex(startTime);
			cal.add(Calendar.DAY_OF_MONTH, diff);
			sdf = new SimpleDateFormat("yyyy-MM-dd EEEE");
			for (int i = 0, j = (diff >= 0 ? 0 : 1); i < next; j = 1, i ++) {
				Map map = new HashMap();
				cal.add(Calendar.DAY_OF_MONTH, 7 * j);
				map.put("schedule", sdf.format(cal.getTime()));
				list.add(map);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return list;
	}

	/**
	 *  获取给定时间的起往前几天的时间段毫秒值
	 */
	public Map<String, Long> get7days(String date, int count){
		Map<String, Long> result = new HashMap<String, Long>();
		try {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date d = sdf.parse(date);
		result.put("endTime", d.getTime() + 1000 * 24 * 3600);
		Calendar cal = Calendar.getInstance();
		cal.setTime(d);
		cal.add(Calendar.DAY_OF_MONTH, 1-count);
		result.put("startTime", cal.getTimeInMillis());
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return result;
	}

	// 查询预约未处理前的信息
	public Message queryOrder(Map<String, String> parameters) {
		Message msg = new Message();
		String date = Tools.getDesc(parameters.get("date"), DateUtil.formatDate(new Date()));
		// 获取7天时间
		Map<String, Long> dates = get7days(date, 70);
		// 按时间分组查出每天有多少人
		List dateList = QBuilder.db("basedb").queryHql("select new map(count(id) as count, CONCAT(FROM_UNIXTIME(registerTime / 1000, '%Y-%m-%d'), '') as register_time, (case when execTime is NULL then '' else CONCAT(FROM_UNIXTIME(execTime / 1000, '%Y-%m-%d %H:%i'), '') end) as exec_time) from Order where hospital = " + parameters.get("hospital") + " and status = " + STATUS_ENABLE + " and state in (" + STATE_ADD +","+ STATE_ADD_CANCEL + ") and registerTime >= " + dates.get("startTime") + " and registerTime <= " + dates.get("endTime")  + " group by FROM_UNIXTIME(registerTime / 1000, '%Y-%m-%d') order by FROM_UNIXTIME(registerTime / 1000, '%Y-%m-%d') desc");
		if (dateList.size() == 0) {
			setErrcode(msg, NO_RESULT);
			return msg;
		}
		// 查询时间下的具体预约人信息
		List orderList = QBuilder.db("basedb").queryHql("select new map(o.id as order_id, o.title as title, o.serviceId as service_id, o.state as state, CONCAT(FROM_UNIXTIME(o.registerTime / 1000, '%Y-%m-%d'), '') as register_time, o.userName as name, o.phone as phone, (case when o.execTime is NULL then '' else CONCAT(FROM_UNIXTIME(o.execTime / 1000, '%Y-%m-%d %H:%i'), '') end) as exec_time) from Order as o where o.hospital = " + parameters.get("hospital") + " and o.status = " + STATUS_ENABLE + " and o.state in (" + STATE_ADD +","+ STATE_ADD_CANCEL + ") and o.registerTime >= " + dates.get("startTime") + " and o.registerTime <= " + dates.get("endTime") + " order by FROM_UNIXTIME(o.registerTime / 1000, '%Y-%m-%d') desc, o.state asc");
		for (int i = 0; i < orderList.size(); i++) {
			Map map = (Map)orderList.get(i);
			String registerTime = map.get("register_time") + "";
			for (int j = 0; j < dateList.size(); j++) {
				Map dateMap = (Map)dateList.get(j);
				if (registerTime.equals((String)dateMap.get("register_time"))) {
					List groups = (List)dateMap.get("groups");
					if (groups == null) {
						groups = new ArrayList();
						dateMap.put("groups", groups);
					}
					groups.add(map);
				}
			}
		}
		msg.put("orders", dateList);
		return msg;
	}

	// 查询预约已处理的信息
	public Message queryHandle(Map<String, String> parameters, Token token) {
		Message msg = new Message();
		int doctorUid = token.getUid();
		String date = Tools.getDesc(parameters.get("date"), DateUtil.formatDate(new Date()));
		List list = QBuilder.db("basedb").queryHql("select new map(o.id as order_id, o.title as title, o.state as state, o.userName as name, o.phone as phone, o.serviceId as service_id, o.doctor as doctor_uid, o.doctorName as doctor_name, (case when o.execTime is NULL then '' else CONCAT(FROM_UNIXTIME(o.execTime / 1000, '%Y-%m-%d %H:%i'), '') end) as exec_time) from Order as o where o.hospital = " + parameters.get("hospital") + " and o.status = " + STATUS_ENABLE + " and o.state in (" + STATE_HANDLED +","+ STATE_OVER + "," + STATE_HANDLED_CANCEL + ") and doctor = " + doctorUid + " and CONCAT(FROM_UNIXTIME(o.execTime / 1000, '%Y-%m-%d'), '') ='" + date + "' order by o.state asc");
		if (list.size() == 0) {
			setErrcode(msg, NO_RESULT);
			return msg;
		}
		Map map = new HashMap();
		map.put("groups", list);
		list = new ArrayList();
        list.add(map);
		msg.put("orders", list);
		return msg;
	}

	// 获取科室预约的信息
	public Message info(Map<String, String> parameters) {
		Message msg = new Message();
		List services = QBuilder.db("basedb").queryHql("select new map(id as service_id, name as service_name) from Service where hospital = " + parameters.get("hospital") + " and status = " + STATUS_ENABLE);
		if (services.size() == 0) {
			setErrcode(msg, NO_RESULT);
			return msg;
		}
		List list = QBuilder.db("basedb").select("new map(ss.doctorUid as doctor_uid, ss.doctorName as doctor_name, ss.serviceId as service_id, ss.price as price, ss.date as date, ss.half as half)").from("ServiceSchedule as ss").where(new Where("ss.hospital = ", parameters.get("hospital")).and("ss.status = ", STATUS_ENABLE)).query().getResultObj();

		List<String> weeksList = Arrays.asList(weeks_check);
		for (int i = 0; i < list.size(); i ++) {
			Map temp = (Map)list.get(i);
			String date = ((String)temp.get("date")).trim();
			if (!weeksList.contains(date))
				continue;
			List<Map> tempList = getPeriodOfTime(date, 4);
			for (int j = 0; j < tempList.size(); j ++) {
				Map tempMap = tempList.get(j);
				tempMap.put("half", (Integer)temp.get("half"));
				tempMap.put("name", (Integer)temp.get("half") == 1 ? "上午" : ((Integer)temp.get("half") == 2 ? "下午" : "全天"));
			}
			temp.remove("half");
			temp.put("date", tempList);
		}

		// 把医生信息放入预约类型中
		List totalDoctor = QBuilder.db("basedb").queryHql("select new map(name as doctor_name, id  as doctor_uid) from User where hospital = " + parameters.get("hospital") + " and type =" + USER_EMPLOYEE);
		//List totalDoctor = QBuilder.db("basedb").queryHql("select new map(name as doctor_name, id  as doctor_uid) from User where hospital in (" + parameters.get("hospital") +","+ 2000 + ") and type =" + USER_EMPLOYEE);
		for (int i = 0; i < services.size(); i ++) {
			Map temp = (Map)services.get(i);
			List doctors = new ArrayList();
			Integer id = (Integer)temp.get("id");
			for (int j = 0; j < list.size(); j ++) {
				Map doctor = (Map)list.get(j);
				if (id != null && id.equals((Integer)doctor.get("service_id"))) {
					doctors.add(doctor);
				}
			}
			if (doctors.size() == 0) {
				temp.put("doctors", totalDoctor);
			} else {
				List tempList = new ArrayList();
				for (int j = 0; j < doctors.size(); j ++) {
					Map doctor = (Map)doctors.get(j);
					Integer doctorUid = (Integer)doctor.get("doctor_uid");
					boolean add = true;
					for (int k = 0; k < tempList.size(); k ++) {
						Map tempDoctor = (Map)tempList.get(k);
						if (doctorUid != null && doctorUid.equals((Integer)tempDoctor.get("doctor_uid"))) {
							List dateList = (List)tempDoctor.get("date");
							dateList.addAll((List)doctor.get("date"));
							add = false;
							break;
						}
					}
					if (add) {
						tempList.add(doctor);
					}
				}
					/* for (int k = 0; k < tempList.size(); k ++) { // 过滤当天的时间以9:00 、12:00为准
					Map tempDoctor = (Map)tempList.get(k);
					List dateList = (List)tempDoctor.get("date");
					for(Iterator it = dateList.iterator(); it.hasNext();){
						tempDoctor = (Map)it.next();
						String date = tempDoctor.get("schedule") + "";
						int half = (Integer)tempDoctor.get("half");
						switch (checkTime(date)) {
							case 1:
								if (half == 1)
									it.remove();
								break;
							case 2:
								it.remove();
								break;
							default:
								break;
							}
					}
				} */
				for (int k = 0; k < tempList.size(); k ++) {  // 按时间排序
					Map tempDoctor = (Map)tempList.get(k);
					List dateList = (List)tempDoctor.get("date");
					Collections.sort(dateList, new Comparator() {

						@Override
						public int compare(Object o1, Object o2) {
							Map first = (Map)o1;
							Map second = (Map)o2;
							return (first.get("schedule") + "").compareTo((second.get("schedule") + ""));
						}
					});
				}
				temp.put("doctors", tempList);
			}
		}
		msg.put("infos", services);
		return msg;
	}

	// 查询人数
	public Message count(Map<String, String> parameters) {
		Message msg = new Message();
		List list = QBuilder.db("basedb").queryHql("select count(id) as number from Order where CONCAT(FROM_UNIXTIME(execTime / 1000, '%Y-%m-%d'), '') = '" + parameters.get("date") + "' and doctor = " + parameters.get("doctor_uid") + " and hospital = " + parameters.get("hospital") + " and status = " + STATUS_ENABLE + " and state = " + STATE_HANDLED);
		if (list.size() == 0) {
			setErrcode(msg, NO_RESULT);
			return msg;
		}
		msg.put("number", list.get(0));
		return msg;
	}

	// 预约处理
	public Message arrange(Map<String, String> parameters, String act) {
		Message msg = new Message();
		Order order = Order.fromMap(parameters, Order.class);
		String date = Tools.getDesc(parameters.get("date"), "");
		if ("".equals(date)) {
			setErrcode(msg, FAILURE);
			return msg;
		}
		order.setExecTime(DateUtil.parseDate(date).getTime());
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
			Date d = sdf.parse(date);
			order.setExecTime(d.getTime());
			sdf = new SimpleDateFormat("HH:mm");
			String str = sdf.format(d);
			if (str.compareTo("12:00") < 0) {
				order.setHalf(1);
			} else {
				order.setHalf(2);
			}
		} catch (ParseException e) {
			e.printStackTrace();
		}
		Order o = (Order)queryItem(order);
		if (o == null) {
			setErrcode(msg, NO_RESULT);
			return msg;
		}
		if (!"modify".equals(act) && o.getState() != STATE_ADD) { // 防止重复提交
			setErrcode(msg, HAVE_HANDLE);
			return msg;
		}
		order.setUid(o.getUid());
		order.setUserName(o.getUserName());
		if (arranged(order, o, act)) {  // 安排手术不能同一天
			setErrcode(msg, HAVE_HANDLE);
			return msg;
		}
		String json = o.getJsonString();
		order.setJsonString(json);
		if (!modifyItem(order)) {
			setErrcode(msg, NO_RESULT);
			return msg;
		}
		if ("modify".equals(act)) {
			List<Timeline> timelines = QBuilder.db("basedb").queryHql("from Timeline where oid = " + order.getId() + " order by id desc");
			if (timelines.size() > 0) {
				Timeline timeline = timelines.get(0);
				timeline.setType(order.getTitle());
				modifyItem(timeline);
			}
		}
		// 创建时间轴
		if (!"modify".equals(act)) {
			o = (Order)queryItem(order);
			Timeline timeline = new Timeline();
			timeline.setPatientUid(o.getUid());
			timeline.setModUid(o.getDoctor());
			timeline.setDoctorUid(o.getDoctor());
			timeline.setOid(o.getId());
			timeline.setKind(TIME_LINE_OPERATE);
			timeline.setType(o.getTitle());
			timeline.setHospital(o.getHospital());
			timeline.setJsonString("{}");
			timeline.setStatus(STATUS_ENABLE);
			timeline.setcTime(System.currentTimeMillis());
			timeline.setDate(DateUtil.formatDate(new Date()));
			timeline.setName("手术类型");
			createItem(timeline);
		}
		msg.put("order", order);
		return msg;
	}

	// 是否已经安排过
	public boolean arranged(Order order, Order o, String act) {
		String time = DateUtil.formatDate(new Date(order.getExecTime()));
		String oldTime = "";
		if (o.getExecTime() != null) {
			oldTime = DateUtil.formatDate(new Date(o.getExecTime()));
		}
		List<String> orderDates = QBuilder.db("basedb").queryHql("select CONCAT(FROM_UNIXTIME(execTime / 1000, '%Y-%m-%d'), '') from Order where uid = " + order.getUid() + " and doctor = " + order.getDoctor() + " and serviceId = " + order.getServiceId() + " and hospital = " + order.getHospital());
		if ("modify".equals(act) && oldTime.equals(time)) {
			return false;
		} else {
			if (orderDates.contains(time)) {
				return true;
			}
		}
		return false;
	}

	// 修改订单
	public Message modifyOrder(Map<String, String> parameters, Token token) {
		Message msg = new Message();
		Order order = Order.fromMap(parameters, Order.class);
		if (repeatSubmit(order)) {
			setErrcode(msg, HAVE_COMMITED);
			return msg;
		}
		if (!modifyItem(order)) {
			setErrcode(msg, NO_RESULT);
			return msg;
		}
		Order o = (Order)queryItem(order);
		if (o.getExecTime() != null)
			parameters.put("date", DateUtil.formatDate(new Date(o.getExecTime())));
		if (order.getState() == STATE_ADD_CANCEL) {
			return queryOrder(parameters);
		}
		if (order.getState() == STATE_HANDLED_CANCEL || order.getState() == STATE_OVER) {
			return queryHandle(parameters, token);
		}
		return msg;
	}

	// 判断是否已做
	public boolean repeatSubmit(Order order) {
		List list = QBuilder.db("basedb").queryHql("from Order where id = " + order.getId() + " and state = " + order.getState());
		if (list.size() > 0) {
			return true;
		} else {
			return false;
		}
	}

	// 查看已安排详细信息
	public Message queryHandleDetail(Map<String, String> parameters) {
		Message msg = new Message();
		Order order = Order.fromMap(parameters, Order.class);
		List list = QBuilder.db("basedb").queryHql("select new map(CONCAT(FROM_UNIXTIME(execTime / 1000, '%Y-%m-%d %H:%i'), '') as exec_time, title as service_name, serviceId as service_id, doctor as doctor, doctorName as doctor_name) from Order where id = " + order.getId() + " and status = " + STATUS_ENABLE + " and state = " + STATE_HANDLED);
		if (list.size() == 0) {
			setErrcode(msg, NO_RESULT);
			return msg;
		}
		msg = info(parameters);
		if (msg.getErrcode() == 0) {
			msg.put("order", list.get(0));
		}
		return msg;
	}

	// 预约信息
	public Message createOrder(Map<String, String> parameters) {
		Message msg = new Message();
		Order order = Order.fromMap(parameters, Order.class);
		if (parameters.get("date") != null)
		order.setExecTime(DateUtil.parseDate(parameters.get("date")).getTime());
		order.setRegisterTime(System.currentTimeMillis());
		order.setConfirm(0);
		String phone = order.getPhone();
		if (phone == null || phone.length() != 11) {
			setErrcode(msg, PHONE_ILLEGAL);
			return msg;
		}
		if (repeatOrder(order)) {
			// setErrcode(msg, HAVE_COMMITED);
			msg.setErrcodeAndErrmsg(HAVE_COMMITED, "当天已预约该套餐，无需重复预约");
			return msg;
		}
		Integer id = createItem(order); // 提交一个预约信息
		if(id == null) {
			setErrcode(msg, RESPONSE_FAILED);
		} else {
			msg.put("id", id);
		}
		return msg;
	}

	// 手术类型
	public Message queryOperateType(Map<String, String> parameters) {
		Message msg = new Message();
		Service service = Service.fromMap(parameters, Service.class);
		List services = new ArrayList();
		if (service.getParentId() != null && service.getParentId() > 0) {
			services = QBuilder.db("basedb").queryHql("select new map(id as service_id, name as service_name) from Service where hospital = " + service.getHospital() + " and status = " + STATUS_ENABLE + " and parentId = " + service.getParentId());
		} else {
			services = QBuilder.db("basedb").queryHql("select new map(id as service_id, name as service_name) from Service where hospital = " + service.getHospital() + " and status = " + STATUS_ENABLE + " and (parentId is NULL or parentId <= 0) order by id asc");
		}
		if (services.size() == 0) {
			setErrcode(msg, NO_RESULT);
		} else {
			msg.put("services", services);
		}
		return msg;
	}

	// 判断是否重复预约
	public boolean repeatOrder(Order order) {
		if (order.getExecTime() != null) {
			// 是否已经预约过（眼科）
			String time = DateUtil.formatDate(new Date(order.getExecTime()));
			List<String> orderDates = QBuilder.db("basedb").queryHql("select CONCAT(FROM_UNIXTIME(execTime / 1000, '%Y-%m-%d'), '') from Order where uid = " + order.getUid() + " and serviceId = " + order.getServiceId() + " and hospital = " + order.getHospital() + " and state < 3 and status =" + STATUS_ENABLE);
			if (orderDates.contains(time)) {
				return true;
			}
		} else {
			// 是否已经预约过
			String time = DateUtil.formatDate(new Date(order.getRegisterTime()));
			List<String> orderDates = QBuilder.db("basedb").queryHql("select CONCAT(FROM_UNIXTIME(registerTime / 1000, '%Y-%m-%d'), '') from Order where uid = " + order.getUid() + " and serviceId = " + order.getServiceId() + " and hospital = " + order.getHospital() + " and state < 3 and status =" + STATUS_ENABLE);
			if (orderDates.contains(time)) {
				return true;
			}
		}
		return false;
	}

	// 查询我的预约
	public Message my(Map<String, String> parameters, Token token) {
		Message msg = new Message();
		Order order = Order.fromMap(parameters, Order.class);
		order.setUid(token.getUid());
		List list = QBuilder.db("basedb").select("new map(o.id as order_id, o.userName as user_name, o.phone as phone, o.state as order_state, o.jsonString as json, o.doctorName as doctor_name, o.doctor as doctor_uid, o.uid as uid, CONCAT(FROM_UNIXTIME(o.registerTime / 1000, '%Y-%m-%d'), '') as register_time, CONCAT(FROM_UNIXTIME(o.execTime / 1000, '%Y-%m-%d'), '') as exec_time, o.title as service_name, o.half as half)").from("Order as o").where(new Where("o.uid = ", order.getUid()).and("o.status = ", STATUS_ENABLE).and("o.hospital = ", order.getHospital())).order("o.registerTime","desc").query().getResultObj();
		if (list.size () == 0) {
			setErrcode(msg, NO_RESULT);
		} else {
			msg.put("orders", list);
		}
		return msg;
	}

	//取消预约
	public Message cancel(Map<String, String> parameters) {
		Message msg = new Message();
		List<Order> list = QBuilder.db("basedb").select().from("Order").where(new Where("hospital=", parameters.get("hospital")).and("status=", STATUS_ENABLE).and("id=", parameters.get("order_id"))).page(1,1).query().getResultObj();
		if (list.size() == 0 && list.get(0).getState() != STATE_ADD) {
			msg.setErrcodeAndErrmsg(30001, "预约检查状态异常");
		} else {
			Order order = list.get(0);
			order.setState(STATE_ADD_CANCEL);
			DBTools.db("basedb").modItem(order, order.getId());
		}
		return msg;
	}

%>
